package com.tanhua.server.service;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.dubbo.config.annotation.Reference;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.mongodb.client.result.DeleteResult;
import com.tanhua.common.enums.SexEnum;
import com.tanhua.common.exception.BusinessException;
import com.tanhua.common.mapper.*;
import com.tanhua.common.pojo.*;
import com.tanhua.common.utils.UserThreadLocal;
import com.tanhua.common.vo.ErrorResult;
import com.tanhua.dubbo.server.api.HuanXinApi;
import com.tanhua.dubbo.server.api.RecommendUserApi;
import com.tanhua.dubbo.server.api.UserLikeApi;
import com.tanhua.dubbo.server.api.UsersApi;
import com.tanhua.dubbo.server.pojo.RecommendUser;
import com.tanhua.dubbo.server.pojo.UserLike;
import com.tanhua.dubbo.server.pojo.Visitors;
import com.tanhua.server.vo.*;
import com.tanhua.sms.SmsTemplate;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.yaml.snakeyaml.events.Event;

import java.time.Duration;
import java.util.*;


@Service
@Slf4j
public class MyCenterService {

    @Autowired
    private UserInfoMapper userInfoMapper;

    @Autowired
    private QuestionMapper questionMapper;

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private SettingsMapper settingsMapper;

    @Autowired
    private SmsTemplate smsTemplate;

    @Autowired
    private RedisTemplate<String, String> redisTemplate;

    @Reference
    private RecommendUserApi recommendUserApi;

    @Autowired
    private MyCenterService myCenterService;

    @Autowired
    private BlackUserService blackUserService;

    @Reference
    private UserLikeApi userLikeApi;

    @Reference(version = "1.0.0")
    private HuanXinApi huanXinApi;

    @Reference(version = "1.0.0")
    private UsersApi usersApi;

    //读取用户信息
    public UserInfoVo queryUserInfoByUserId(Long userId) {
        if (ObjectUtil.isEmpty(userId)) {
            //如果查询id为null，就表示查询当前用户信息
            userId = UserThreadLocal.get().getId();
        }
        //查询用户信息
        UserInfo userInfo = userInfoMapper.selectById(userId);
        if (ObjectUtil.isEmpty(userInfo)) {
            return null;
        }

        UserInfoVo userInfoVo = BeanUtil.copyProperties(userInfo, UserInfoVo.class, "marriage");
        userInfoVo.setGender(userInfo.getSex().getValue() == 1 ? "man" : "women");
        userInfoVo.setMarriage(StrUtil.equals("已婚", userInfo.getMarriage()) ? 1 : 0);
        return userInfoVo;
    }

    //保存用户信息
    public Boolean updateUserInfo(UserInfoVo userInfoVo) {
        User user = UserThreadLocal.get();
        UserInfo userInfo = new UserInfo();
        userInfo.setUserId(user.getId());
        userInfo.setNickName(userInfoVo.getNickname());
        userInfo.setAge(Integer.valueOf(userInfoVo.getAge()));
        userInfo.setSex(StringUtils.equalsIgnoreCase(userInfoVo.getGender(), "man") ? SexEnum.MAN : SexEnum.WOMAN);
        userInfo.setBirthday(userInfoVo.getBirthday());
        userInfo.setCity(userInfoVo.getCity());
        userInfo.setEdu(userInfoVo.getEducation());
        userInfo.setIncome(StringUtils.replaceAll(userInfoVo.getIncome(), "K", ""));
        userInfo.setIndustry(userInfoVo.getProfession());
        userInfo.setMarriage(userInfoVo.getMarriage() == 1 ? "已婚" : "未婚");
        LambdaUpdateWrapper<UserInfo> wrapper = new LambdaUpdateWrapper<>();
        wrapper.eq(UserInfo::getUserId, user.getId());
        return this.userInfoMapper.update(userInfo, wrapper) > 0;
    }

    //查看黑名单
    public PageResult queryBlacklist(Integer page, Integer pageSize) {
        //获取当前用户
        User user = UserThreadLocal.get();
        //获取黑名单列表
        IPage<BlackUser> blackUserIPage = blackUserService.queryBlackList(page, pageSize);
        //新建一个储存黑名单用户的集合
        List<BlackUserVo> blackUsers = new ArrayList<>();
        //遍历黑名单列表
        for (BlackUser blackUser : blackUserIPage.getRecords()) {
            //获取黑名单用户id
            Long blackUserId = blackUser.getUserId();
            //判断 删除黑名单用户和当前用户的关系
            //huanXinApi.removeUserFriend(user.getId(), blackUserId);
            usersApi.removeUsers(user.getId(), blackUserId);
            BlackUserVo blackUserVo = new BlackUserVo();
            //根据黑名单用户id查询黑名单userinfo
            UserInfo userInfo = userInfoMapper.selectById(blackUser.getBlackUserId());
            blackUserVo.setId(blackUser.getId());
            blackUserVo.setAvatar(userInfo.getLogo());
            blackUserVo.setNickname(userInfo.getNickName());
            blackUserVo.setGender(userInfo.getSex().getValue() == 1 ? "man" : "woman");
            blackUserVo.setAge(userInfo.getAge());
            blackUsers.add(blackUserVo);
        }

        PageResult pageResult = new PageResult();
        pageResult.setPage(page);
        pageResult.setPagesize(pageSize);
        pageResult.setItems(blackUsers);
        pageResult.setPages((int) blackUserIPage.getPages());
        pageResult.setCounts(blackUsers.size());

        return pageResult;
    }

    //黑名单  移除
    public int blackListRemove(String id) {
        return blackUserService.blackListRemove(id);
    }

    //喜欢 - 取消
    public void dislike(String id) {
        //获取当前用户
        User user = UserThreadLocal.get();
        Long userId = user.getId();
        userLikeApi.dislike(userId, id);
    }

    //粉丝 - 喜欢
    public void fansLove(String likeUserId) {
        User user = UserThreadLocal.get();
        Long userId = user.getId();
        userLikeApi.fansLove(userId, likeUserId);

    }

    //设置用户问题
    public void saveQuestion(String content) {
        //获取登录用户id
        Long uid = UserThreadLocal.get().getId();
        try {
            //查询用户是否已经设置问题
            LambdaQueryWrapper<Question> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(Question::getUserId, uid);
            Question question = questionMapper.selectOne(wrapper);

            //如果不存在,则添加
            if (ObjectUtil.isEmpty(question)) {
                question = new Question();
                question.setUserId(uid);
                question.setTxt(content);
                questionMapper.insert(question);
            } else {
                question.setTxt(content);
                questionMapper.updateById(question);
            }
        } catch (Exception e) {
            log.error("设置陌生人问题失败!,用户id:" + uid + ",问题内容为:" + content, e);
            throw new BusinessException(ErrorResult.saveQuestionFail());
        }
    }

    //查询用户设置信息
    public SettingsVo querySettings() {
        //获取当前登录用户
        Long uid = UserThreadLocal.get().getId();
        try {
            //查询用户设置
            //1.查询用户手机号
            LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(User::getId, uid);
            User user = userMapper.selectOne(wrapper);

            //2.查询用户问题
            LambdaQueryWrapper<Question> qwrapper = new LambdaQueryWrapper<>();
            qwrapper.eq(Question::getUserId, uid);
            Question question = questionMapper.selectOne(qwrapper);

            //3.查询用户设置
            LambdaQueryWrapper<Settings> swrapper = new LambdaQueryWrapper<>();
            swrapper.eq(Settings::getUserId, uid);
            Settings settings = settingsMapper.selectOne(swrapper);
            //封装vo对象
            SettingsVo settingsVo = new SettingsVo();
            settingsVo.setId(user.getId());
            settingsVo.setPhone(user.getMobile());
            settingsVo.setGonggaoNotification(settings.getGonggaoNotification() == 1);
            settingsVo.setPinglunNotification(settings.getPinglunNotification() == 1);
            settingsVo.setLikeNotification(settings.getLikeNotification() == 1);
            settingsVo.setStrangerQuestion(question.getTxt());
            return settingsVo;
        } catch (Exception e) {
            e.printStackTrace();
            log.error("用户设置查询失败！用户id:" + uid, e);
        }
        return null;
    }

    //保存用户通知设置
    public void saveNotifications(Map<String, Boolean> map) {
        //获取登录用户id
        Long uid = UserThreadLocal.get().getId();
        try {
            Settings settings = new Settings();
            settings.setLikeNotification(map.get("likeNotification") ? 1 : 0);
            settings.setGonggaoNotification(map.get("gonggaoNotification") ? 1 : 0);
            settings.setPinglunNotification(map.get("pinglunNotification") ? 1 : 0);

            //封装设置对象
            LambdaQueryWrapper<Settings> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(Settings::getUserId, uid);
            settingsMapper.update(settings, wrapper);
        } catch (Exception e) {
            e.printStackTrace();
            log.error("用户通知设置保存失败！用户id:" + uid, e);
        }


    }

    //修改手机号_发送验证码
    public boolean sendVerificationCode() {
        //获取当前登录用户
        Long uid = UserThreadLocal.get().getId();
        //查询用户手机号
        String mobile = UserThreadLocal.get().getMobile();
        //设置redis中保存验证码的key值
        String redisKey = "UPDATE_CODE_" + mobile;
        //根据手机号获取redis中的值
        String value = redisTemplate.opsForValue().get(redisKey);
        //查询redis中是否存在验证码
        if (StrUtil.isNotEmpty(value)) {
            throw new BusinessException(ErrorResult.redisKeyError());
        }
        //调用sms服务发送短信
        //String code = smsTemplate.sendSms(mobile);
        String code = "123456";

        //将验证码存入redis中
        redisTemplate.opsForValue().set(redisKey, code, Duration.ofMinutes(5));
        return true;


    }

    //修改手机号_校验验证码
    public Map<String, Object> checkVerificationCode(String code) {

        Map<String, Object> map = new HashMap<>();
        //获取当前登录用户
        Long uid = UserThreadLocal.get().getId();
        //查询用户手机号
        LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(User::getId, uid);
        User user = userMapper.selectOne(wrapper);
        String mobile = user.getMobile();

        //设置redis中保存验证码的key值
        String redisKey = "UPDATE_CODE_" + mobile;
        //根据手机号获取redis中的值
        String value = redisTemplate.opsForValue().get(redisKey);
        //查询redis中是否存在验证码
        if (StrUtil.isEmpty(value)) {
            throw new BusinessException(ErrorResult.loginError());
        }

        if (!StrUtil.equals(code, value)) {
            throw new BusinessException(ErrorResult.checkCodeError());
        }

        map.put("verification", true);
        return map;
    }

    //保存新手机号
    public void updatePhone(String phone) {
        Long uid = UserThreadLocal.get().getId();
        String oldPhone = UserThreadLocal.get().getMobile();
        //判断新手机号与原手机号是否相同
        if (StrUtil.equals(phone, oldPhone)) {
            throw new BusinessException(ErrorResult.updatePhoneFail());
        }

        LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(User::getMobile, phone);
        User selectOne = userMapper.selectOne(wrapper);
        //判断新手机号否已经存在
        if (ObjectUtil.isNotEmpty(selectOne)) {
            throw new BusinessException(ErrorResult.updatePhoneFail());
        }

        //更新用户手机号
        User user = new User();
        user.setMobile(phone);
        user.setId(uid);
        userMapper.updateById(user);
    }

    //查询用户互相喜欢、喜欢、粉丝、谁看过我列表
    public PageResult queryUser(String type, Integer page, Integer pageSize, String nickName) {
        //获取当前登录用户id
        Long uid = UserThreadLocal.get().getId();
        PageResult pageResult = new PageResult();
        //判断查询列表类型
        switch (type) {
            case "1": {
                pageResult = mutualLikeUser(uid, page, pageSize, nickName);
                break;
            }
            case "2": {
                pageResult = myLikeUser(uid, page, pageSize, nickName);
                break;
            }
            case "3": {
                pageResult = likeMeUser(uid, page, pageSize, nickName);
                break;
            }
            case "4": {
                pageResult = lookMeUser(uid, page, pageSize);
                break;
            }
            default:
                pageResult = null;
                break;

        }

        return pageResult;
    }

    //看过我的
    private PageResult lookMeUser(Long uid, Integer page, Integer pageSize) {
        PageResult pageResult = new PageResult();
        pageResult.setPage(page);
        pageResult.setPagesize(pageSize);
        List<Visitors> visitorsList = userLikeApi.queryLookMeUser(uid, page, pageSize);
        if (CollUtil.isEmpty(visitorsList)) {
            pageResult.setPage(page);
            pageResult.setPagesize(pageSize);
            pageResult.setCounts(0);
            return pageResult;
        }

        List<Object> visitorUserId = CollUtil.getFieldValues(visitorsList, "visitorUserId");

        //获取喜欢用户详细信息集合
        List<UserInfo> userInfoList = queryList(visitorUserId);

        List<LikeUserVo> likeUserVoList = new ArrayList<>();
        //封装vo对象
        for (UserInfo userInfo : userInfoList) {
            LikeUserVo likeUserVo = new LikeUserVo();
            BeanUtil.copyProperties(userInfo, likeUserVo, "marriage");
            likeUserVo.setGender(userInfo.getSex().getValue() == 1 ? "man" : "woman");
            likeUserVo.setMarriage(StrUtil.equals("已婚", userInfo.getMarriage()) ? 1 : 0);
            likeUserVo.setAge(userInfo.getAge().intValue());
            RecommendUser recommendUser = recommendUserApi.queryScore(uid, userInfo.getUserId().toString());
            if (ObjectUtil.isEmpty(recommendUser)) {
                recommendUser = new RecommendUser();
                recommendUser.setScore(80D);
            }
            likeUserVo.setMatchRate(recommendUser.getScore().intValue());
            likeUserVo.setAlreadyLove(userLikeApi.isLike(uid, userInfo.getUserId()));
            likeUserVoList.add(likeUserVo);
        }

        pageResult.setItems(likeUserVoList);
        return pageResult;

    }

    //喜欢我的
    private PageResult likeMeUser(Long uid, Integer page, Integer pageSize, String nickName) {
        PageResult pageResult = new PageResult();
        pageResult.setPage(page);
        pageResult.setPagesize(pageSize);
        List<UserLike> likeUserList = userLikeApi.queryLikeMeUser(uid, page, pageSize);
        //获取我喜欢的用户id集合
        List<Object> likeUserIds = CollUtil.getFieldValues(likeUserList, "userId");
        if (CollUtil.isEmpty(likeUserIds)) {
            pageResult.setPage(page);
            pageResult.setPagesize(pageSize);
            pageResult.setCounts(0);
            return pageResult;
        }

        //获取喜欢用户详细信息集合
        List<UserInfo> userInfoList = queryList(likeUserIds, nickName, page, pageSize);

        List<LikeUserVo> likeUserVoList = new ArrayList<>();
        //封装vo对象
        for (UserInfo userInfo : userInfoList) {
            LikeUserVo likeUserVo = new LikeUserVo();
            BeanUtil.copyProperties(userInfo, likeUserVo, "marriage");
            likeUserVo.setGender(userInfo.getSex().getValue() == 1 ? "man" : "woman");
            likeUserVo.setMarriage(StrUtil.equals("已婚", userInfo.getMarriage()) ? 1 : 0);
            likeUserVo.setAge(userInfo.getAge().intValue());
            RecommendUser recommendUser = recommendUserApi.queryScore(uid, userInfo.getUserId().toString());
            if (ObjectUtil.isEmpty(recommendUser)) {
                recommendUser = new RecommendUser();
                recommendUser.setScore(80D);
            }
            likeUserVo.setMatchRate(recommendUser.getScore().intValue());
            likeUserVo.setAlreadyLove(userLikeApi.isAlreadyLike(userInfo.getUserId() + "", uid));
            likeUserVoList.add(likeUserVo);
        }

        pageResult.setItems(likeUserVoList);
        return pageResult;
    }

    //我喜欢的
    private PageResult myLikeUser(Long uid, Integer page, Integer pageSize, String nickName) {
        PageResult pageResult = new PageResult();
        pageResult.setPage(page);
        pageResult.setPagesize(pageSize);
        List<UserLike> likeUserList = userLikeApi.queryMyLikeUser(uid, page, pageSize);
        //获取我喜欢的用户id集合
        List<Object> likeUserIds = CollUtil.getFieldValues(likeUserList, "likeUserId");
        if (CollUtil.isEmpty(likeUserIds)) {
            pageResult.setPage(page);
            pageResult.setPagesize(pageSize);
            pageResult.setCounts(0);
            return pageResult;
        }
        //获取喜欢用户详细信息集合
        List<UserInfo> userInfoList = queryList(likeUserIds, nickName, page, pageSize);
        List<LikeUserVo> likeUserVoList = new ArrayList<>();
        //封装vo对象
        for (UserInfo userInfo : userInfoList) {
            LikeUserVo likeUserVo = new LikeUserVo();
            BeanUtil.copyProperties(userInfo, likeUserVo, "marriage");
            likeUserVo.setGender(userInfo.getSex().getValue() == 1 ? "man" : "woman");
            likeUserVo.setMarriage(StrUtil.equals("已婚", userInfo.getMarriage()) ? 1 : 0);
            likeUserVo.setAge(userInfo.getAge().intValue());
            RecommendUser recommendUser = recommendUserApi.queryScore(uid, userInfo.getUserId().toString());
            if (ObjectUtil.isEmpty(recommendUser)) {
                recommendUser = new RecommendUser();
                recommendUser.setScore(80D);
            }
            likeUserVo.setMatchRate(recommendUser.getScore().intValue());
            likeUserVo.setAlreadyLove(true);
            likeUserVoList.add(likeUserVo);
        }
        pageResult.setItems(likeUserVoList);
        return pageResult;
    }

    //互相喜欢
    private PageResult mutualLikeUser(Long uid, Integer page, Integer pageSize, String nickName) {
        //新建返回对象
        PageResult pageResult = new PageResult();
        pageResult.setPage(page);
        pageResult.setPagesize(pageSize);
        //查询互相喜欢集合
        List<UserLike> likeUserList = userLikeApi.mutualLikeUser(uid, page, pageSize);
        //获取我喜欢的用户id集合
        List<Object> likeUserIds = CollUtil.getFieldValues(likeUserList, "likeUserId");
        if (CollUtil.isEmpty(likeUserIds)) {
            pageResult.setPage(page);
            pageResult.setPagesize(pageSize);
            pageResult.setCounts(0);
            return pageResult;
        }
        //获取喜欢用户详细信息集合
        List<UserInfo> userInfoList = queryList(likeUserIds, nickName, page, pageSize);
        List<LikeUserVo> likeUserVoList = new ArrayList<>();
        //封装vo对象
        for (UserInfo userInfo : userInfoList) {
            LikeUserVo likeUserVo = new LikeUserVo();
            BeanUtil.copyProperties(userInfo, likeUserVo, "marriage");
            likeUserVo.setGender(userInfo.getSex().getValue() == 1 ? "man" : "woman");
            likeUserVo.setMarriage(StrUtil.equals("已婚", userInfo.getMarriage()) ? 1 : 0);
            likeUserVo.setAge(userInfo.getAge().intValue());
            RecommendUser recommendUser = recommendUserApi.queryScore(uid, userInfo.getUserId().toString());
            if (ObjectUtil.isEmpty(recommendUser)) {
                recommendUser = new RecommendUser();
                recommendUser.setScore(80D);
            }
            likeUserVo.setMatchRate(recommendUser.getScore().intValue());
            likeUserVo.setAlreadyLove(true);
            likeUserVoList.add(likeUserVo);
        }
        pageResult.setItems(likeUserVoList);
        return pageResult;
    }

    //统计
    public Map<String, Integer> queryCounts() {
        //获取当前用户对象
        User user = UserThreadLocal.get();
        Long userId = user.getId();
        //查询当前用户喜欢的用户 粉丝 互相喜欢的用户数
        Long likes = userLikeApi.queryMyLikeUserCount(userId);
        Long fans = userLikeApi.queryLikeMeUserCount(userId);
        Long eachloves = userLikeApi.mutualLikeUserCount(userId);
        //按照前端需要的数据 封装map
        Map<String, Integer> map = new HashMap<>();
        map.put("eachLoveCount", Math.toIntExact(eachloves));
        map.put("loveCount", Math.toIntExact(likes));
        map.put("fanCount", Math.toIntExact(fans));

        return map;
    }

    //是否已喜欢
    public Boolean isAlreadyLove(String id) {
        //获取当前用户
        User user = UserThreadLocal.get();
        Long userId = user.getId();
        //判断推荐用户在不在喜欢用户列表中
        return userLikeApi.isAlreadyLike(id, userId);

    }

    //查询用户详细信息列表
    private List<UserInfo> queryList(List<Object> likeUserIds, String nickName, Integer page, Integer pageSize) {
        List<Long> uIds = new ArrayList<>();
        for (Object id : likeUserIds) {
            uIds.add(Convert.toLong(id));
        }


        LambdaQueryWrapper<UserInfo> wrapper = new LambdaQueryWrapper<>();
        wrapper.in(UserInfo::getUserId, uIds);
        if (StrUtil.isNotEmpty(nickName)) {
            page = page - 1;
            wrapper.like(UserInfo::getNickName, nickName);
        }
        IPage<UserInfo> iPage = new Page<>(page, pageSize);

        IPage<UserInfo> pageResult = userInfoMapper.selectPage(iPage, wrapper);
        return pageResult.getRecords();
    }

    //查询用户详细信息列表(谁看过我)
    public List<UserInfo> queryList(List<Object> likeUserIds) {

        List<Long> uIds = new ArrayList<>();
        for (Object id : likeUserIds) {
            uIds.add(Convert.toLong(id));
        }

        List<UserInfo> userInfoList = new ArrayList<>();
        for (Long uId : uIds) {
            LambdaQueryWrapper<UserInfo> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(UserInfo::getUserId, uId);
            UserInfo userInfo = userInfoMapper.selectOne(wrapper);
            userInfoList.add(userInfo);
        }
        return userInfoList;
    }
}
